package fcc.Seng462project.server;

/* Server side implementation of BlobService
  */

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import fcc.Seng462project.client.BlobService;
import fcc.Seng462project.client.entities.FileInfo;
import fcc.Seng462project.client.entities.ShareInfo;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@SuppressWarnings("serial")
public class BlobServiceImpl extends RemoteServiceServlet implements
    BlobService {

  //Start Google App Engine BlobstoreService & Objectify sessions 
  BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
  Objectify ofy = ObjectifyService.begin();
  
  
  //Register the Objectify Service for the FileInfo and ShareInfo entities
  static {
    ObjectifyService.register(FileInfo.class);
    ObjectifyService.register(ShareInfo.class);
  }

  //Generate a Blobstore Upload URL from the GAE BlobstoreService
  @Override
  public String getBlobStoreUploadUrl() {
    //Map the UploadURL to the uploadservice which will be called by
    //submitting the FormPanel
	String surl = blobstoreService.createUploadUrl("/upload");
  return surl;
  }
  
  //Retrieve the Blob's info from the Datastore using Objectify
  @Override
  public ArrayList<FileInfo> getFileInfo(String username) {
	Query<FileInfo> q = ofy.query(FileInfo.class).filter("owner", username);
	ArrayList<FileInfo> files = new ArrayList<FileInfo>();
	
	//loop query results and add to array
	for (FileInfo fetched : q) {
		files.add(fetched);
	}
	return files;
  }
  
  //get all shared files, return as an ArrayList
  public ArrayList<FileInfo> getSharedFiles(String username) {
	ArrayList<FileInfo> files = new ArrayList<FileInfo>();
	Query<ShareInfo> q1 = ofy.query(ShareInfo.class).filter("owner", username);
	for (ShareInfo share : q1) {
		Query<FileInfo> q2 = ofy.query(FileInfo.class).filter("blobkey", share.blobkey);
		//loop query results and add to array
		for (FileInfo fetched : q2) {
			files.add(fetched);
		}
	}
	return files;
  }
  
  //share a file with another user
  public void shareFile(String shareUsername, String blobkey) {
	  ShareInfo share = new ShareInfo();
	  share.setUsername(shareUsername);
	  share.setBlobkey(blobkey);
	  ofy.put(share);
  }
  
  //delete a file
  public void deleteBlob(String blobkey) {
	  Query<FileInfo> q = ofy.query(FileInfo.class).filter("blobkey", blobkey);
	  for (FileInfo file: q) {
		  ofy.delete(file);
	  }
	  BlobKey blobKey = new BlobKey(blobkey);
	  blobstoreService.delete(blobKey);
  }
  
  //Override doGet to serve blobs. 
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
        BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));
        blobstoreService.serve(blobKey, resp);

  }
}